package id.co.rho.scoring.cid.client.widgets;

import id.co.rho.scoring.cid.shared.utils.DirtyAwareComboBoxPriorityComparator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import gxt.visual.ui.client.implementations.VFormBinding;

import com.extjs.gxt.ui.client.binding.Bindings;
import com.extjs.gxt.ui.client.binding.FieldBinding;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.BindingEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;

public class ChangeTrackingSupportFormBinding extends VFormBinding {

	public ChangeTrackingSupportFormBinding(FormPanel panel, boolean autoBind) {
		super(panel, autoBind);
	}

	public ChangeTrackingSupportFormBinding(FormPanel panel) {
		super(panel);
	}

	@Override
	public void autoBind() {
		DirtyAwareSimpleComboBox combo;
		for (Field<?> f : panel.getFields()) {
			if (!bindings.containsKey(f.getId())) {
				String name = f.getName();
				if (name != null && name.length() > 0) {
					//combo box bind
					if(f instanceof DirtyAwareSimpleComboBox){
						combo = (DirtyAwareSimpleComboBox) f;
						ChangeTrackingSupportSimpleComboBinding c = new ChangeTrackingSupportSimpleComboBinding(combo, f.getName());
						bindings.put(f.getId(), c);
					}else if(f instanceof DirtyAwareComboBox){
						ChangeTrackingSupportComboBoxBinding cb = new ChangeTrackingSupportComboBoxBinding(f, f.getName());
						bindings.put(f.getId(), cb);
					}else{
						ChangeTrackingSupportFieldBinding b = new ChangeTrackingSupportFieldBinding(f, f.getName());
						bindings.put(f.getId(), b);
					}
				}
			}
		}
	}
	
	@Override
	public void bind(final ModelData model){
		DeferredCommand.addCommand(new Command() {
		      public void execute() {
		        BindingEvent e = new BindingEvent(ChangeTrackingSupportFormBinding.this, model);
		        if (fireEvent(Events.BeforeBind, e)) {
		          if (ChangeTrackingSupportFormBinding.this.model != null) {
		        	  unbind();
		          }
		          ChangeTrackingSupportFormBinding.this.model = model;
		          //from map to list
		          List<FieldBinding> bindList = new ArrayList();
		          for (FieldBinding binding : bindings.values()) {
			            bindList.add(binding);
			      }
		          
		          //filter
		          List<FieldBinding> bindListWithPriority = new ArrayList();
		          List<FieldBinding> bindListWithoutPriority = new ArrayList();
		          DirtyAwareComboBox combo;
		          for (FieldBinding binding : bindList) {
		        	  Field f = binding.getField();
		        	  if(f instanceof DirtyAwareComboBox){
		        		  combo = (DirtyAwareComboBox) f;
		        		  if(combo.getPriority()!=null){
		        			  bindListWithPriority.add(binding);
		        		  }else{
		        			  bindListWithoutPriority.add(binding);
		        		  }
		        	  }else{
		        		  bindListWithoutPriority.add(binding);
		        	  }
			      }
		          
		          //sort bindListWithPriority
		          Collections.sort(bindListWithPriority, new DirtyAwareComboBoxPriorityComparator());
		          //bind bindListWithPriority
		          for (FieldBinding binding : bindListWithPriority) {
		        	  binding.bind(model);
		          }
		          //bind bindListWithoutPriority
		          for (FieldBinding binding : bindListWithoutPriority) {
		        	  binding.bind(model);
		          }
		          
		          fireEvent(Events.Bind, e);
		        }
		      }
		    });
	}

}
